#include "../StdInc.h"

namespace GSTrader
{
	namespace TradeStrategy
	{
		CMarketDataProviderManager::CMarketDataProviderManager(CFramework* pFramework) : CProviderManager(pFramework)
		{
		}


		CMarketDataProviderManager::~CMarketDataProviderManager()
		{
		}

		CMarketDataProvider* CMarketDataProviderManager::GetMarketDataConnByInfo(CConnectionInfo* pInfo)
		{
			if (pInfo == NULL || m_mapProvider.size() == 0)
				return NULL;

			for (auto p : m_mapProvider)
			{
				CMarketDataProvider* pProvider = dynamic_cast<CMarketDataProvider*>(p.second);
				if (pProvider && *pProvider == *pInfo)
				{
					return pProvider;
				}
			}

			return NULL;
		}

		CMarketDataProvider* CMarketDataProviderManager::ConnMarketDataServer(CConnectionInfo* pInfo, CSubscribeInstrument* pSubscribe)
		{
			if (pInfo == NULL || pInfo->m_pBroker == NULL || pInfo->m_pBroker->m_nPlatformType < 0)
			{
				assert(false);
				return NULL;
			}

			CConnectionInfo* pUser = new CConnectionInfo(*pInfo);
			CMarketDataProvider* pProvider = GetMarketDataConnByInfo(pInfo);
			
			if (pProvider)
			{
				return pProvider;
			}
			else
			{
				pProvider = new CMarketDataClient(m_pFramework, pUser->m_pBroker->m_nPlatformType);
			}
			
			if (pSubscribe)
			{
				m_pFramework->m_pSubscriptionManager->AddSubscribe(pProvider->GetProviderId(), pSubscribe);
			}

			if (!pProvider->IsConnected())
			{
				if (pProvider->Connect(pUser) < 0)
				{
					_delete(pProvider)
					return NULL;
				}
			}

			return pProvider;
		}

		void CMarketDataProviderManager::GetMarketDataProvider(vector<CMarketDataProvider*>& vMarketDataProvider)
		{
			for (auto p : m_mapProvider)
			{
				CMarketDataProvider* pProvider = dynamic_cast<CMarketDataProvider*>(p.second);
				if (pProvider)
				{
					vMarketDataProvider.push_back(pProvider);
				}
			}
		}

		CMarketDataProvider* CMarketDataProviderManager::GetMarketDataProvider(CConnectionInfo* pConnnectionInfo)
		{
			if (pConnnectionInfo == NULL)
				return NULL;

			for (auto p : m_mapProvider)
			{
				if (*p.second == *pConnnectionInfo)
				{
					return dynamic_cast<CMarketDataProvider*>(p.second);
				}
			}

			return NULL;
		}

		CMarketDataProvider* CMarketDataProviderManager::GetFirstProvider()
		{
			for (auto it : m_mapProvider)
			{
				CMarketDataProvider* pMarketDataProvider = dynamic_cast<CMarketDataProvider*>(it.second);
				if (pMarketDataProvider && pMarketDataProvider->IsConnected())
					return pMarketDataProvider;
			}

			return NULL;
		}

		CMarketDataProvider* CMarketDataProviderManager::GetProviderByType(int nType)
		{
			for (auto it : m_mapProvider)
			{
				CMarketDataProvider* pMarketDataProvider = dynamic_cast<CMarketDataProvider*>(it.second);
				if (pMarketDataProvider && pMarketDataProvider->IsConnected())
				{
					if (pMarketDataProvider->GetConnectionInfo()->m_pBroker->m_nPlatformType == nType)
						return pMarketDataProvider;
				}
			}

			return NULL;
		}

		CMarketDataProvider* CMarketDataProviderManager::GetProviderById(int nProviderId)
		{
			CProvider* p = GetProvider(nProviderId);
			if (p /*&& p->m_nProviderType == pvtMarketData*/)
			{
				return dynamic_cast<CMarketDataProvider*>(p);
			}

			return NULL;
		}

		void CMarketDataProviderManager::OnFrontDisconnected(CAccountData* pAccount)
		{
			CMarketDataProvider* pMarketDataProvider = GetProviderById(pAccount->m_nProviderId);
			if (pMarketDataProvider)
			{
				pMarketDataProvider->OnDisconnect(pAccount);
			}
		}
	}
}
